<template>
  <NavBarHeader class="navbar-header">
    <template #title>视频通话</template>
  </NavBarHeader>
  <div class="call-page">
    <!-- 视频区域 -->
    <div class="video-container">
      <video id="localVideo" autoplay muted class="video"></video>
      <video id="remoteVideo" autoplay class="video"></video>
    </div>
    <!-- 通话控制按钮 -->
    <div class="control-panel">
      <button @click="startCall">开始通话</button>
      <button @click="endCall">结束通话</button>
    </div>
  </div>
</template>

<script setup>
import { ref, onBeforeUnmount } from 'vue'
import { WS_BASE_URL } from '@/utils/constant'
import { useRoute } from 'vue-router'
import { useUserStore } from '@/stores/user'
import router from '@/router'
import { HEART_MESSAGE } from '@/utils/constant'
import { showFailToast } from 'vant'

const localStream = ref(null)
const remoteStream = ref(null)
const peerConnection = ref(null)
const store = useUserStore()
const route = useRoute()
const ws = ref(null)
ws.value = new WebSocket(WS_BASE_URL + `/ws?token=${store.token}&session=true`)
console.log('WebSocket连接: ', ws.value)
ws.value.onopen = () => {
  console.log('WebSocket连接已建立......')
}
const targetUserId = route.query.targetUserId
console.log('targetUserId', targetUserId)
// WebRTC配置
const config = {
  iceServers: [{ urls: 'stun:stun.l.google.com:19302' }] // 使用 Google 的公共 STUN 服务器
}

peerConnection.value = new RTCPeerConnection(config)

console.log('peerConnection 初始化完成')

const sendMessage = (message) => {
  ws.value.send(JSON.stringify(message))
}

const startCall = async () => {
  try {
    console.log('获取本地流')
    localStream.value = await navigator.mediaDevices.getUserMedia({
      video: true,
      audio: true
    })
  } catch (error) {
    console.log('无法获取摄像头或麦克风', error)
    showFailToast('无法获取摄像头或麦克风')
  }

  document.getElementById('localVideo').srcObject = localStream.value

  localStream.value.getTracks().forEach((track) => {
    console.log('getTracks')
    peerConnection.value.addTrack(track, localStream.value)
  })

  peerConnection.value.ontrack = (event) => {
    console.log('ontrack')
    if (!remoteStream.value) {
      console.log('remoteStream.value', remoteStream.value)
      remoteStream.value = new MediaStream()
      document.getElementById('remoteVideo').srcObject = remoteStream.value
    }
    remoteStream.value.addTrack(event.track)
  }

  peerConnection.value.onicecandidate  = (event) => {
    if (event.candidate) {
      console.log('发送 ice-candidate',event.candidate)
      sendMessage({
        type: 'ice-candidate',
        candidate: event.candidate,
        targetUserId: targetUserId
      })
    }
  }

  const offer = await peerConnection.value.createOffer()
  await peerConnection.value.setLocalDescription(offer)
  sendMessage({ type: 'offer', offer, targetUserId: targetUserId })
}

const endCall = () => {
  peerConnection.value.close()
  peerConnection.value = null
  localStream.value.getTracks().forEach((track) => track.stop())
  localStream.value = null
  remoteStream.value = null
}

ws.value.onopen = () => {
  console.log('服务已连接')
}

ws.value.onclose = () => {
  console.log('服务未连接')
}

ws.value.onerror = (error) => {
  console.log('WebSocket 错误:', error)
}

ws.value.onmessage = (event) => {
  if (event.data === HEART_MESSAGE) {
    // 忽略心跳消息
    console.warn('接收到心跳消息......')
    return
  }
  const message = JSON.parse(event.data)

  if (message.type === 'offer') {
    console.log('接收到消息: offer', message)
    handleOffer(message)
  } else if (message.type === 'answer') {
    console.log('接收到消息: answer', message)
    handleAnswer(message)
  } else if (message.type === 'ice-candidate') {
    console.log('接收到消息: ice-candidate', message)
    handleIceCandidate(message)
  }
}

const handleOffer = async (message) => {
  if (!peerConnection.value) {
    console.log('peerConnection 未初始化')
    return
  }
  // 提取 targetUserId
  const { offer, targetUserId } = message // 解构获取 offer 和 targetUserId
  if (peerConnection.value.signalingState === 'stable') {
    console.log('peerConnection.value.signalingState offer', peerConnection.value.signalingState)
    // 你可以调用 setRemoteDescription
    await peerConnection.value.setRemoteDescription(
      new RTCSessionDescription(offer)
    )
  } else {
    console.error(
      '无法设置远程描述，当前信令状态：',
      peerConnection.value.signalingState
    )
  }

  const answer = await peerConnection.value.createAnswer()
  await peerConnection.value.setLocalDescription(answer)
  sendMessage({ type: 'answer', answer, targetUserId: targetUserId })
}

const handleAnswer = async (answer) => {
  console.log('answer', answer)
  console.log('当前 signalingState:', peerConnection.value.signalingState)
  if (peerConnection.value.signalingState === 'stable') {
    console.log('peerConnection.value.signalingState answer', peerConnection.value.signalingState)
    // 你可以调用 setRemoteDescription
    await peerConnection.value.setRemoteDescription(
      new RTCSessionDescription(answer.answer)
    )
  } else {
    console.error(
      '无法设置远程描述，当前信令状态：',
      peerConnection.value.signalingState
    )
  }
}

const handleIceCandidate = async (message) => {
  console.log('接收到消息: ice-candidate', message)
  try {
    if (message.candidate) {
      await peerConnection.value.addIceCandidate(
        new RTCIceCandidate(message.candidate)
      )
      console.log('ICE Candidate 已添加')
    }
  } catch (error) {
    console.error('添加 ICE Candidate 失败', error)
  }
}
</script>

<style scoped>
.navbar-header {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  z-index: 1000;
}

.call-page {
  display: flex;
  flex-direction: column;
  height: 100vh;
}

.video-container {
  flex: 1; /* 让视频容器占满剩余空间 */
  display: flex; /* 使用 flex 布局 */
  flex-direction: column; /* 垂直排列 */
  justify-content: center; /* 垂直居中 */
  align-items: center; /* 水平居中 */
  background-color: #000;
  padding: 20px;
}

.video-container video {
  width: 90%; /* 控制视频宽度 */
  height: auto;
  max-height: 45%; /* 限制最大高度 */
  margin-bottom: 10px; /* 增加上下间距 */
  background-color: #333;
  border-radius: 10px;
}

.control-panel {
  position: fixed; /* 固定在页面底部 */
  bottom: 0;
  left: 0;
  width: 100%;
  padding: 10px;
  display: flex;
  justify-content: center;
  gap: 10px;
  background-color: #f5f5f5;
  border-radius: 10px 10px 0 0; /* 顶部圆角 */
  box-shadow: 0 -2px 5px rgba(0, 0, 0, 0.1); /* 添加阴影效果 */
}

button {
  padding: 10px 20px;
  font-size: 16px;
  border: none;
  border-radius: 5px;
  background-color: #007bff;
  color: white;
  cursor: pointer;
}

button:hover {
  background-color: #0056b3;
}
</style>
